function [ SOA ] = structarray2structofarray( s, squeezeFields, recursive, autoTransMat )
%STRUCTARRAY2STRUCTOFARRAY 将结构体数组转换为包含数组的结构体
%
% Input Arguments
% # s: 结构体数组，尺寸为szStruct
% # squeezeFields: 逻辑标量，true表示删掉结果中长度为1的维数，默认为true
% # recursive: 逻辑标量，true表示对s中的子结构体标量递归调用本函数，默认为true
% # autoTransMat: 逻辑标量，true表示如果squeeze后的结果为行数小于列数的二维数值矩阵，则自动转置该矩阵，默认为true
%
% Output Arguments
% # SOA: 结构体标量，包含的各域与s相同，各域的尺寸在原有的基础上扩展了szStruct维（不考虑squeeze）

% NOTE: 本函数使用线性索引

if nargin < 4
    autoTransMat = true;
end
if nargin < 3
    recursive = true;
end
if nargin < 2
    squeezeFields = true;
end

if isstruct(s)
    names = fieldnames(s);
    for i=1:length(names)
        SOA.(names{i}) = structarrayfield2array(s, names{i});
        if squeezeFields
            SOA.(names{i}) = squeeze(SOA.(names{i}));
        end
        if autoTransMat && isnumeric(SOA.(names{i})) && ismatrix(SOA.(names{i}))
            [m, n] = size(SOA.(names{i}));
            if m < n
                SOA.(names{i}) = (SOA.(names{i}))';
            end
        end
        if recursive && isstruct(SOA.(names{i}))
            SOA.(names{i}) = structarray2structofarray(SOA.(names{i}), squeezeFields, recursive);
        end
    end
else
    warning('structarray2structofarray:typeerror', 's is not a struct.');
end
